package wsi.gui.config;

import java.io.File;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.ToggleGroup;
import javafx.stage.DirectoryChooser;

import org.rygh.gui.comp.Button;
import org.rygh.gui.comp.CheckBox;
import org.rygh.gui.comp.Label;
import org.rygh.gui.comp.RadioButton;
import org.rygh.gui.comp.TextField;
import org.rygh.gui.model.Presenter;
import org.rygh.gui.view.GridView;

import wsi.script.AppConfig;
import wsi.script.AppParameter;
import wsi.script.AppScriptInitializer;
import wsi.script.AppXml;
import wsi.task.Engine.InputSelectType;

public class ConfigView extends GridView {
	private final String[] KBS = { AppXml.YAGO, AppXml.MBZ, AppXml.IMDB };
	private final RadioButton[] kbBtns = new RadioButton[KBS.length];

	private final String[] INPUTS = { InputSelectType.Random.name(),
			InputSelectType.Degree.name(), InputSelectType.Feedback.name() };
	private final RadioButton[] inputBtns = new RadioButton[INPUTS.length];

	private final TextField expBaseField = new TextField();
	private final TextField runField = new TextField();
	private final TextField inputSizeField = new TextField("100");

	private final CheckBox webCacheCheck = new CheckBox();
	private final CheckBox inputSelectCheck = new CheckBox();

	public ConfigView(Presenter presenter) {
		super(presenter);

		init();
	}

	private void clear() {
		runField.clear();
		expBaseField.clear();
	}

	private void init() {
		setVgap(6);
		setHgap(6);

		int y = 0;

		add(new Label("Knowledge Base"), 0, y);

		ToggleGroup tg = new ToggleGroup();

		for (int i = 0; i < KBS.length; i++) {
			kbBtns[i] = new RadioButton(KBS[i]);
			kbBtns[i].setToggleGroup(tg);
			kbBtns[i].setSelected(i == 0);

			add(kbBtns[i], i + 1, y);
		}

		//

		y++;
		add(new Label("Experiment Base"), 0, y);
		add(expBaseField, 1, y, 3, 1);
		expBaseField.setEditable(false);

		//

		Button b = new Button("...");
		b.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				selectFolder();
			}
		});

		y++;
		add(new Label("Run Folder"), 0, y);
		add(runField, 1, y, 3, 1);
		add(b, 4, y);

		//
		y++;
		add(new Label("Web Cache"), 0, y);
		add(webCacheCheck, 1, y);
		webCacheCheck.setSelected(true);

		//
		y++;
		add(new Label("Only Input Select"), 0, y);
		add(inputSelectCheck, 1, y);

		//
		y++;
		add(new Label("Input Size"), 0, y);
		add(inputSizeField, 1, y, 3, 1);

		//
		y++;
		add(new Label("Input Method"), 0, y);

		tg = new ToggleGroup();

		for (int i = 0; i < INPUTS.length; i++) {
			inputBtns[i] = new RadioButton(INPUTS[i]);
			inputBtns[i].setToggleGroup(tg);
			inputBtns[i].setSelected(i == 2);

			add(inputBtns[i], i + 1, y);
		}

		//

		b = new Button("Save");
		b.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				save();
			}
		});

		y++;
		add(b, 4, y);
	}

	private void save() {
		String expBase = expBaseField.getText();

		if (expBase == null || expBase.isEmpty()) {
			getWindow().tooltip(expBaseField,
					"Invalid experiment folder structure.");
			return;
		}

		for (int i = 0; i < kbBtns.length; i++)
			if (kbBtns[i].isSelected()) {
				AppParameter.KNOWLEDGE_DATABASE = KBS[i];
				break;
			}

		for (int i = 0; i < inputBtns.length; i++)
			if (inputBtns[i].isSelected()) {
				AppParameter.INPUT_SELECT_TYPE = InputSelectType
						.valueOf(inputBtns[i].getText());
				break;
			}

		AppParameter.WEB_CACHE_ON = webCacheCheck.isSelected();
		AppParameter.SELECTED_TREES_ON = !inputSelectCheck.isSelected();
		AppParameter.RESOLVE_ON = !inputSelectCheck.isSelected();

		AppParameter.LOCAL_PREFIX = expBaseField.getText();
		AppParameter.LOCAL_DIR = runField.getText();
		AppParameter.LOCAL_INPUT_SIZE = Integer.parseInt(inputSizeField
				.getText());

		File file = new File(String.format("%s/runs/%s", expBase,
				runField.getText()), "config.xml");
		file.delete();

		AppConfig.reset();
		AppConfig.init(file.getAbsolutePath());
		AppConfig as = AppConfig.shared();
		assert as != null;

		as.setTree(AppScriptInitializer.initTree(true));
		as.save();
	}

	private void selectFolder() {
		DirectoryChooser dc = new DirectoryChooser();
		dc.setTitle("Select Experiment Base Folder");
		dc.setInitialDirectory(new File(System.getProperty("user.home")));
		File d = dc.showDialog(getWindow());

		if (d == null)
			return;

		File runs = d.getParentFile();

		if (!runs.getName().equals("runs")) {
			getWindow().tooltip(expBaseField,
					"Invalid experiment folder structure.");
			clear();
			return;
		}

		runField.setText(d.getName());
		expBaseField.setText(runs.getParentFile().getAbsolutePath());

	}

}
